package com.gzhryc.shared_device.oem.code.place.services;

import com.gzhryc.common.StringTools;
import com.gzhryc.common.data.TreeUtils;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.jdbc.Conditions;
import com.gzhryc.jdbc.MultiDBTools;
import com.gzhryc.shared_device.oem.code.place.dao.PlacePhysicalStoreTypeDao;
import com.gzhryc.shared_device.oem.code.place.dao.db.PlacePhysicalStoreType;

import java.sql.SQLException;
import java.util.Date;
import java.util.List;

public class PlacePhysicalStoreTypeService {

    static Logger log = Logger.getLogger(PlacePhysicalStoreTypeService.class);

    public static PlacePhysicalStoreTypeService self() {
        return MultiDBTools.getService(PlacePhysicalStoreTypeService.class, true);
    }

    PlacePhysicalStoreTypeDao dao;

    public PlacePhysicalStoreTypeService(String jdbcKey) {
        this.dao = new PlacePhysicalStoreTypeDao(jdbcKey);
    }

    public List<PlacePhysicalStoreType> findJoinAll() {
        try {
            return dao.findJoinAll();
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public List<PlacePhysicalStoreType> findAll() {
        Conditions condition = new Conditions(PlacePhysicalStoreType.class);
        condition.asc("priority");
        try {
            return dao.findByCondition(condition);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public List<PlacePhysicalStoreType> findTree() {
        Conditions condition = new Conditions(PlacePhysicalStoreType.class);
        condition.asc("priority");
        try {
            List<PlacePhysicalStoreType> data = dao.findByCondition(condition);
            if (data != null) {
                return TreeUtils.byTree(data);
            }
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    public List<PlacePhysicalStoreType> findRoot() {
        Conditions condition = new Conditions(PlacePhysicalStoreType.class);
        condition.and().isNull("parentId").or().is("parentId", 0L);
        try {
            return dao.findByCondition(condition);
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    public List<PlacePhysicalStoreType> findByParentId(Long parentId) {
        if(parentId != null) {
            Conditions condition = new Conditions(PlacePhysicalStoreType.class);
            condition.and().is("parentId", parentId);
            try {
                return dao.findByCondition(condition);
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }

    public String[] getNames(String[] codes) {
        if (codes != null && codes.length > 0) {
            boolean flag = false;
            String[] result = new String[codes.length];
            for (int i = 0; i < codes.length; i++) {
                String code = codes[i];
                PlacePhysicalStoreType storeType = getByCode(code);
                if (storeType != null) {
                    result[i] = storeType.getName();
                    flag = true;
                } else {
                    break;
                }
            }
            if(flag) {
                return result;
            }
        }
        return null;
    }

    public PlacePhysicalStoreType getById(Long id){
        try {
            return dao.getById(id);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public PlacePhysicalStoreType getJoinById(Long id){
        try {
            return dao.getJoinById(id);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public PlacePhysicalStoreType getByCode(String code){
        if(StringTools.isNotBlank(code)) {
            Conditions conditions = new Conditions(PlacePhysicalStoreType.class);
            conditions.and().is("code",code);
            try {
                return dao.get(conditions);
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }

    public boolean add(PlacePhysicalStoreType type) throws LogicException {
        PlacePhysicalStoreType temp = getByCode(type.getCode());
        if(temp != null){
            throw new LogicException("Code已存在");
        }
        if(type.getPriority() == null){
            type.setPriority(10);
        }
        type.setCreateDate(new Date());
        try {
            return dao.insert(type) > 0;
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return false;
    }

    public boolean save(PlacePhysicalStoreType physicalStoreType) throws LogicException {
        try {
            PlacePhysicalStoreType temp = getByCode(physicalStoreType.getCode());
            if(temp != null){
                if(!temp.getName().equals(physicalStoreType.getName())){
                    try {
                        PlacePhysicalStoreType updateEntity = new PlacePhysicalStoreType();
                        updateEntity.setId(temp.getId());
                        updateEntity.setName(physicalStoreType.getName());
                        if(dao.updateNotNull(updateEntity) <= 0){
                            log.error("修改网点类型失败，类型：{{0:json}}",physicalStoreType);
                        }
                    } catch (SQLException e) {
                        log.error(e.getMessage(),e);
                    }
                }
                physicalStoreType.setId(temp.getId());
            }else {
                if (dao.insert(physicalStoreType) <= 0) {
                    throw new LogicException("新增网点类型" + physicalStoreType.getName()
                            + "(" + physicalStoreType.getCode() + ")失败");
                }
            }

            if(physicalStoreType.getChildren() != null && physicalStoreType.getChildren().size() > 0){
                for(PlacePhysicalStoreType child : physicalStoreType.getChildren()){
                    child.setParentId(physicalStoreType.getId());
                    save(child);
                }
            }

            return true;
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return false;
    }

    public boolean updateNotNull(PlacePhysicalStoreType type) throws LogicException{
        PlacePhysicalStoreType temp = getByCode(type.getCode());
        if(temp != null && !temp.getId().equals(type.getId())){
            throw new LogicException("Code已存在");
        }
        try {
            return dao.updateNotNull(type) > 0;
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return false;
    }

    public boolean deleteById(Long id)throws LogicException{
        try {
            return dao.deleteById(id) > 0;
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return false;
    }
}
